import pytest
import requests
import json
from unittest.mock import patch, MagicMock
import time
import random

# 配置信息
API_URL = "https://cvm.tencentcloudapi.com/"
REGION = "ap-guangzhou"
SECRET_ID = "your-secret-id"
SECRET_KEY = "your-secret-key"


def generate_signature(params, SECRET_KEY):
    """生成签名（模拟实现）"""
    return "mock-signature"


def send_request(action, params=None):
    """发送API请求（模拟实现）"""
    if params is None:
        params = {}
    common_params = {
        "Action": action,
        "Version": "2017-03-12",
        "Region": REGION,
        "SecretId": SECRET_ID,
        "Timestamp": int(time.time()),
        "Nonce": random.randint(1, 1000000),
        "SignatureMethod": "HmacSHA256"
    }
    all_params = {**common_params, **params}
    all_params["Signature"] = generate_signature(all_params, SECRET_KEY)

    response = requests.post(API_URL, data=all_params)
    return response.json()


class TestInquiryPriceRenewInstances:
    @patch('requests.post')
    def test_success(self, mock_post):
        """测试成功获取重装实例价格"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Price": {
                    "OriginalPrice": 100.0,
                    "DiscountPrice": 80.0
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-123456",
            "SystemDisk": {
                "DiskType": "CLOUD_PREMIUM",
                "DiskSize": 50
            }
        }
        result = send_request("InquiryPriceRenewInstances", params)

        assert "Response" in result
        assert "Price" in result["Response"]
        assert "OriginalPrice" in result["Response"]["Price"]
        assert "DiscountPrice" in result["Response"]["Price"]

    @patch('requests.post')
    def test_inquiry_price_failed(self, mock_post):
        """测试询价失败"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "FailedOperation.InquiryPriceFailed",
                    "Message": "询价失败"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceId": "ins-failed"}
        result = send_request("InquiryPriceRenewInstances", params)
        assert result["Response"]["Error"]["Code"] == "FailedOperation.InquiryPriceFailed"

    @patch('requests.post')
    def test_internal_trade_error(self, mock_post):
        """测试交易内部未知错误"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InternalError.TradeUnknownError",
                    "Message": "内部错误"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceId": "ins-trade-error"}
        result = send_request("InquiryPriceRenewInstances", params)
        assert result["Response"]["Error"]["Code"] == "InternalError.TradeUnknownError"

    @patch('requests.post')
    def test_internal_server_error(self, mock_post):
        """测试内部服务器错误"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InternalServerError",
                    "Message": "操作内部错误"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceId": "ins-internal-error"}
        result = send_request("InquiryPriceRenewInstances", params)
        assert result["Response"]["Error"]["Code"] == "InternalServerError"

    @patch('requests.post')
    def test_invalid_image_id_format(self, mock_post):
        """测试无效镜像ID格式"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidImageId.Malformed",
                    "Message": "错误的镜像Id格式"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-123456",
            "ImageId": "invalid-image-id"
        }
        result = send_request("InquiryPriceRenewInstances", params)
        assert result["Response"]["Error"]["Code"] == "InvalidImageId.Malformed"

    @patch('requests.post')
    def test_image_not_found(self, mock_post):
        """测试镜像不存在"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidImageId.NotFound",
                    "Message": "未找到该镜像"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-123456",
            "ImageId": "img-not-found"
        }
        result = send_request("InquiryPriceRenewInstances", params)
        assert result["Response"]["Error"]["Code"] == "InvalidImageId.NotFound"

    @patch('requests.post')
    def test_unsupported_instance(self, mock_post):
        """测试不支持的实例"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidInstance.NotSupported",
                    "Message": "不被支持的实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceId": "ins-unsupported"}
        result = send_request("InquiryPriceRenewInstances", params)
        assert result["Response"]["Error"]["Code"] == "InvalidInstance.NotSupported"

    @patch('requests.post')
    def test_invalid_instance_id_format(self, mock_post):
        """测试无效实例ID格式"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidInstanceId.Malformed",
                    "Message": "无效实例ID。指定的实例ID格式错误"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceId": "ins-123"}  # 长度错误的实例ID
        result = send_request("InquiryPriceRenewInstances", params)
        assert result["Response"]["Error"]["Code"] == "InvalidInstanceId.Malformed"

    @patch('requests.post')
    def test_instance_not_found(self, mock_post):
        """测试实例不存在"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidInstanceId.NotFound",
                    "Message": "没有找到相应实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceId": "ins-not-found"}
        result = send_request("InquiryPriceRenewInstances", params)
        assert result["Response"]["Error"]["Code"] == "InvalidInstanceId.NotFound"

    @patch('requests.post')
    def test_invalid_parameter_value(self, mock_post):
        """测试参数取值错误"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidParameterValue",
                    "Message": "参数取值错误"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InvalidParam": "invalid"}
        result = send_request("InquiryPriceRenewInstances", params)
        assert result["Response"]["Error"]["Code"] == "InvalidParameterValue"

    @patch('requests.post')
    def test_invalid_instance_id_format_strict(self, mock_post):
        """测试实例ID格式不符合要求"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidParameterValue.InstanceIdMalformed",
                    "Message": "实例ID不合要求，请提供规范的实例ID"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceId": "INS-123456"}  # 包含大写字母的实例ID
        result = send_request("InquiryPriceRenewInstances", params)
        assert result["Response"]["Error"]["Code"] == "InvalidParameterValue.InstanceIdMalformed"

    @patch('requests.post')
    def test_instance_type_not_found(self, mock_post):
        """测试指定机型不存在"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidParameterValue.InstanceTypeNotFound",
                    "Message": "指定机型不存在"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-123456",
            "InstanceType": "invalid-type"
        }
        result = send_request("InquiryPriceRenewInstances", params)
        assert result["Response"]["Error"]["Code"] == "InvalidParameterValue.InstanceTypeNotFound"

    @patch('requests.post')
    def test_invalid_image_operation(self, mock_post):
        """测试镜像不允许执行该操作"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidParameterValue.InvalidImageId",
                    "Message": "镜像不允许执行该操作"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-123456",
            "ImageId": "img-invalid-operation"
        }
        result = send_request("InquiryPriceRenewInstances", params)
        assert result["Response"]["Error"]["Code"] == "InvalidParameterValue.InvalidImageId"

    @patch('requests.post')
    def test_invalid_image_for_reset(self, mock_post):
        """测试镜像无法用于重装当前实例"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidParameterValue.InvalidImageIdForRetsetInstance",
                    "Message": "镜像无法用于重装当前实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-123456",
            "ImageId": "img-invalid-for-reset"
        }
        result = send_request("InquiryPriceRenewInstances", params)
        assert result["Response"]["Error"]["Code"] == "InvalidParameterValue.InvalidImageIdForRetsetInstance"

    @patch('requests.post')
    def test_invalid_os_name(self, mock_post):
        """测试不支持的操作系统"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidParameterValue.InvalidImageOsName",
                    "Message": "当前地域不支持指定镜像所包含的操作系统"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-123456",
            "ImageId": "img-invalid-os"
        }
        result = send_request("InquiryPriceRenewInstances", params)
        assert result["Response"]["Error"]["Code"] == "InvalidParameterValue.InvalidImageOsName"

    @patch('requests.post')
    def test_unsupported_zone(self, mock_post):
        """测试不支持的可用区"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidParameterValue.ZoneNotSupported",
                    "Message": "请求不支持该可用区"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-123456",
            "Zone": "invalid-zone"
        }
        result = send_request("InquiryPriceRenewInstances", params)
        assert result["Response"]["Error"]["Code"] == "InvalidParameterValue.ZoneNotSupported"

    @patch('requests.post')
    def test_missing_parameter(self, mock_post):
        """测试缺少必要参数"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "MissingParameter",
                    "Message": "缺少参数错误"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        result = send_request("InquiryPriceRenewInstances", {})
        assert result["Response"]["Error"]["Code"] == "MissingParameter"

    @patch('requests.post')
    def test_missing_monitor_service(self, mock_post):
        """测试缺少云监控服务参数"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "MissingParameter.MonitorService",
                    "Message": "该实例类型必须开启云监控服务"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceId": "ins-monitor-required"}
        result = send_request("InquiryPriceRenewInstances", params)
        assert result["Response"]["Error"]["Code"] == "MissingParameter.MonitorService"

    @patch('requests.post')
    def test_cloud_disk_unavailable(self, mock_post):
        """测试云盘不可用"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "ResourceInsufficient.CloudDiskUnavailable",
                    "Message": "云盘参数不符合规范"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-123456",
            "SystemDisk": {
                "DiskType": "CLOUD_PREMIUM",
                "DiskSize": -10  # 无效的磁盘大小
            }
        }
        result = send_request("InquiryPriceRenewInstances", params)
        assert result["Response"]["Error"]["Code"] == "ResourceInsufficient.CloudDiskUnavailable"

    @patch('requests.post')
    def test_instance_type_sold_out(self, mock_post):
        """测试实例类型已售罄"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "ResourcesSoldOut.SpecifiedInstanceType",
                    "Message": "指定的实例类型已售罄"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-123456",
            "InstanceType": "type-sold-out"
        }
        result = send_request("InquiryPriceRenewInstances", params)
        assert result["Response"]["Error"]["Code"] == "ResourcesSoldOut.SpecifiedInstanceType"

    @patch('requests.post')
    def test_unsupported_grid_licence(self, mock_post):
        """测试不支持GridLicence"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InstanceTypeNotSupportGridLicence",
                    "Message": "实例类型不支持设置GridDriverService状态"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-123456",
            "GridDriverService": "ENABLED"
        }
        result = send_request("InquiryPriceRenewInstances", params)
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InstanceTypeNotSupportGridLicence"

    @patch('requests.post')
    def test_invalid_license_type(self, mock_post):
        """测试镜像许可类型与实例不符"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InvalidImageLicenseTypeForReset",
                    "Message": "镜像许可类型与实例不符，请选择其他镜像"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-123456",
            "ImageId": "img-invalid-license"
        }
        result = send_request("InquiryPriceRenewInstances", params)
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InvalidImageLicenseTypeForReset"

    @patch('requests.post')
    def test_modify_encryption_unsupported(self, mock_post):
        """测试不支持修改加密属性"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.ModifyEncryptionNotSupported",
                    "Message": "不支持修改系统盘的加密属性"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-encrypted",
            "ImageId": "img-not-encrypted"  # 尝试使用非加密镜像重装加密系统盘
        }
        result = send_request("InquiryPriceRenewInstances", params)
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.ModifyEncryptionNotSupported"

    @patch('requests.post')
    def test_raw_disk_unsupported(self, mock_post):
        """测试不支持对RAW本地磁盘实例重装为QCOW2格式"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.RawLocalDiskInsReinstalltoQcow2",
                    "Message": "当前镜像不支持对该实例的重装操作"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-raw-disk",
            "ImageId": "img-qcow2"
        }
        result = send_request("InquiryPriceRenewInstances", params)
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.RawLocalDiskInsReinstalltoQcow2"

    @patch('requests.post')
    def test_unauthorized_operation(self, mock_post):
        """测试未授权操作"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnauthorizedOperation",
                    "Message": "未授权的操作"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        result = send_request("InquiryPriceRenewInstances", {"InstanceId": "ins-123456"})
        assert result["Response"]["Error"]["Code"] == "UnauthorizedOperation"


# 启动测试函数
def run_tests():
    pytest.main([__file__, "-v", "-s"])


if __name__ == "__main__":
    run_tests()    